#include "input.h"
#include "button.h"
#include "listButton.h"
#include "control.h"
#include "interpolationHelper.h"
#include "drawingWidget.h"
#include "moveButton.h"
#include "textInputButton.h"
#include "colladaLoader.h"
#include "spriteMeshLoader.h"
using namespace msbButton;

//define all static thingys:
Input* Input::inputInstance=NULL;

Input::Input(){

    lastKey=0;

    mouseX=0,
    mouseY=0,

    screenX=0,
    screenY=0,

    windowX=0,
    windowY=0,

    invertMouse=-1,

    startPressLeftBtn=0,
    startPressRightBtn=0,

    numParticles=0;

    pressedLeft=false,
    pressedRight=false,
    pressedMiddle=false,
    bShiftDown=false,
    bCtrlDown=false,
    bAltDown=false,
    bModifierPressed=false,
    bTextInput=false;

    inputText="";
    tooltip="";

    savedDrawingDirName="resources/drawings/",
    savedSceneDirName="resources/scenes/",
    savedActionsDirName="resources/actions/";

    keyVector=Vector3f(0,0,0),          //delta!!!!
    mouseVector=Vector3f(0,0,0),        //delta!!!!
    mouse3D=Vector3f(0,0,0);            //mouse position in 3D coordinates (uses picking)

    gridSize=0.00010f;                      //grid!

    controller=NULL;

    focusButton=NULL;     //the button that gets all our attention
    dragButton=NULL;       // the button we're currently dragging with us
    hudTarget=NULL;       // the button we're currently hovering on
    staticButton=NULL;    //in case we want to access Button functionality without actually displaying a Button

    worldTarget=NULL;
    debugText="Moviesandbox 2.0";

    actorMenu=NULL;
    inputInstance=NULL;
}

Input::~Input(){}

Input* Input::getInstance(){

    if (inputInstance)
        return inputInstance;
    else{
        inputInstance=new Input;
        return inputInstance;
        }
}

void Input::setup(){

renderer=Renderer::getInstance();

windowX=100;
windowY=100;

glutIgnoreKeyRepeat(1);

controller=new Control;

verdana.loadFont("resources/verdana.ttf",8);
verdana.setLineHeight(20.0f);
}

//Here we check all buttons and see if the mouse is hovering over them!
void Input::update(double deltaTime){

    Button *myButton;
    Input::hudTarget=NULL;
    Input::worldTarget=NULL;

    controller->update(deltaTime);
    //reset last pressed key!
    lastKey=0;

    if (staticButton!=NULL){
        staticButton->update(deltaTime);
    }

    for (unsigned int i=0; i<renderer->buttonList.size();i++)
      {
      myButton=renderer->buttonList[i];
      if (myButton->bAlwaysUpdate)
        myButton->update(deltaTime);
      if (Input::mouseX > myButton->location.x && Input::mouseX < myButton->location.x + myButton->scale.x)
         if (Input::mouseY > myButton->location.y && Input::mouseY < myButton->location.y + myButton->scale.y)
           {
           hudTarget=myButton;
           hudTarget->mouseOver();
           }
      }
    Input::mouseVector*=0;

    //for actor menu animation
    if (actorMenu)
     actorMenu->update(deltaTime);

    if (pressedLeft)
      startPressLeftBtn++;
    if (pressedRight)
      startPressRightBtn++;
    //static button functionality for shortcuts and stuff, using the Renderer list of Buttons
}

void Input::pressedMouse(int button,int state,int x, int y){

    // first gather information and select states
    windowX=glutGet( GLUT_WINDOW_X);
    windowY=glutGet( GLUT_WINDOW_Y);

    //don't forget the modifiers!

    if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
      bShiftDown=true;
    else
      bShiftDown=false;


    cout << "state is: " << state << endl;

    //pick if we clicked, just in general...

    //deselect all if we're clicking anywhere and we're not supposed to
    if (!hudTarget  && !focusButton && !dragButton && state==MOUSEBTNRELEASED){
        deselectButtons(0);
        }

    //then check if we're on a button
    if (state==MOUSEBTNRELEASED){

        if (!hudTarget)
            renderer->pick(x,y);
        //we clicked on an actor!
        if (worldTarget && worldTarget->name!="ground" && worldTarget->name!="grid" && worldTarget->name!="brush" && !hudTarget)
          {
          if (button==MOUSEBTNRIGHT){
              cout << "Clicked on: " << worldTarget->name << endl;
              if (actorMenu)
                free(actorMenu);

              actorMenu=new ListButton;
              actorMenu->location.x=mouseX;
              actorMenu->location.y=mouseY;
              actorMenu->listDisplayMode=2;
              actorMenu->listType.assign(worldTarget->menuType.begin(),worldTarget->menuType.end());
              actorMenu->listName.assign(worldTarget->menuName.begin(),worldTarget->menuName.end());
              actorMenu->listIcon.assign(worldTarget->menuIcon.begin(),worldTarget->menuIcon.end());
              actorMenu->listProp.assign(worldTarget->menuProp.begin(),worldTarget->menuProp.end());
              actorMenu->parent=Input::worldTarget;
              actorMenu->clickedLeft();
              }

          if (button==MOUSEBTNLEFT || button==MOUSEBTNRIGHT){
            selectActor(button);
            }
          }else if (!focusButton && !hudTarget){
            deselectActors();
            }


      if(!dragButton){
        if (focusButton)
          {
          cout <<"hovering over: " << hudTarget << endl;
          focusButton->focusClick();
          }
        else if (Input::hudTarget && state==MOUSEBTNRELEASED)
          {
          cout <<"clicked on: " << hudTarget->name << endl;
          if (button==MOUSEBTNLEFT && state==MOUSEBTNRELEASED)
            hudTarget->clickedLeft();
          if (button==MOUSEBTNRIGHT && state==MOUSEBTNRELEASED)
            hudTarget->clickedRight();
          }
        }
        //this is if we have a button dragged...
        else{
          dragButton->finishDrag();
          dragButton=NULL;
        }
      }

    //boolean flags and
    //counting the frames we pressed the button - makes it easy to check against!
    //e.g.: if (Input::startPressRightBtn==0) -> the frame the button got pressed!

    if (button==MOUSEBTNLEFT && state==MOUSEBTNRELEASED)
        {
            pressedLeft=false;
            startPressLeftBtn=0;
        }

    if (button==MOUSEBTNRIGHT && state==MOUSEBTNRELEASED)
        {
            pressedRight=false;
            startPressRightBtn=0;
        }

    if (button==MOUSEBTNLEFT && state==MOUSEBTNPRESSED)   pressedLeft=true;

    if (button==MOUSEBTNRIGHT && state==MOUSEBTNPRESSED)  pressedRight=true;
}


void Input::moveMouse(int x, int y){

if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
  bShiftDown=true;
else
  bShiftDown=false;

if (GLUT_ACTIVE_CTRL==glutGetModifiers())
  bCtrlDown=true;
else
  bCtrlDown=false;


//delta
Input::mouseVector.x=x-Input::mouseX;
Input::mouseVector.y=(y-Input::mouseY)*invertMouse;

Input::mouseX=x;
Input::mouseY=y;
}

void Input::dragMouse(int x, int y){

if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
  bShiftDown=true;
else
  bShiftDown=false;

if (dragButton && dragButton->bDragable){
  dragButton->mouseDrag();
  }
else if (hudTarget && hudTarget->bDragable)
  hudTarget->mouseDrag();

//delta
Input::mouseVector.x=x-Input::mouseX;//yay!
Input::mouseVector.y=(y-Input::mouseY)*invertMouse;

Input::mouseX=x;
Input::mouseY=y;
}


//****************************************************************************************
// Key is pressed down

void Input::normalKeyDown(unsigned char key, int x, int y){

if (!bTextInput)
  {
    if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
      bShiftDown=true;
    else
      bShiftDown=false;

    lastKey=key;
  }
else
  {
    if (key==127 || key==8)                               //pressed Delete!!!
      {
      if (inputText.size()>0)
        inputText.erase(inputText.size()-1);
      }
    else if (key==13)                                     //pressed Enter!!!
      {
      bTextInput=false;
      if (focusButton)                                    //be sure to call back to the button!
        focusButton->focusClick();
      }
    else if (key==27)                                     //pressed ESC!!!
      {
      bTextInput=false;
      Input::deselectButtons(0);
      }
    else
      inputText+=key;
  }
}

void Input::specialKeyDown(int key, int x, int y){

//make this relative to where we look at!
if (key==GLUT_KEY_RIGHT)
       keyVector.x=1;
if (key==GLUT_KEY_LEFT)
       keyVector.x=-1;

if (key==GLUT_KEY_PAGE_UP)
       keyVector.y=1;
if (key==GLUT_KEY_PAGE_DOWN)
       keyVector.y=-1;


if (key==GLUT_KEY_UP)
       keyVector.z=-1;
if (key==GLUT_KEY_DOWN)
       keyVector.z=1;

if (key==GLUT_KEY_END)
       exit(0);

if (GLUT_ACTIVE_SHIFT==glutGetModifiers())
  bShiftDown=true;
else
  bShiftDown=false;
}


//****************************************************************************************
// Key is released

void Input::keyUp(unsigned char key,int x,int y){

Input::windowX=glutGet( GLUT_WINDOW_X);
Input::windowY=glutGet( GLUT_WINDOW_Y);

if (!bTextInput)
  {
    //translate
    if (key=='t'){
        if (staticButton!=renderer->actorInfo["10MoveButton"].actorReference){
          staticButton=(Button*)renderer->actorInfo["10MoveButton"].actorReference;
          renderer->pick(mouseX,mouseY);
          staticButton->parent=worldTarget;
          ((MoveButton*)staticButton)->bActive=true;
        }
        else{
        ((MoveButton*)staticButton)->bActive=false;
        staticButton->parent=NULL;
        staticButton=NULL;
        }
    }

    //rotate
    if (key=='r'){
        if (staticButton!=renderer->actorInfo["12RotateButton"].actorReference){
          staticButton=(Button*)renderer->actorInfo["12RotateButton"].actorReference;
          renderer->pick(mouseX,mouseY);
          staticButton->parent=worldTarget;
          ((RotateButton*)staticButton)->bActive=true;
        }
        else{
        ((RotateButton*)staticButton)->bActive=false;
        staticButton->parent=NULL;
        staticButton=NULL;
        }
    }


    if (key=='-')                               //grid on/off
      if (DrawingWidget::grid)
        DrawingWidget::destroyGrid();
      else
        DrawingWidget::createGrid();

    if (key=='.')                               //switch grid plane
      if (DrawingWidget::grid)
        DrawingWidget::switchGridPlane();

    if (key=='T')                               //trigger selected actor
        if (selectedActors[0])
            selectedActors[0]->trigger(NULL);
    // reload all shaders!
    if (key=='s')
           loadShaders("resources/library.xml");


    if (key==9)                             //pressed TAB
      controller->navBtn->toggle();

    if (key==27)                                     //pressed ESC!!!
      Input::deselectButtons(0);

    if (key==' ')                           //space - run scene //TODO: read these keycommands from an xml file
      controller->switchMode();

    if (key==127 || key==8)                               //pressed Delete!!!
      {
      renderer->pick(mouseX,mouseY);
      if(worldTarget && worldTarget->name!="ground" && worldTarget->bRemoveable){
        for (int i=0; i<(int)selectionMarkers.size();i++){
            if (selectionMarkers[i]->base && selectionMarkers[i]->base==worldTarget){
                delete(selectionMarkers[i]);                                    //delete marker object
                selectedActors.erase(selectedActors.begin()+i);                 //remove from selection stack
                selectionMarkers.erase(selectionMarkers.begin()+i);             //remove marker from marker list
            }
        }
        worldTarget->remove();
        }
      if (hudTarget){
        Node* n=dynamic_cast<Node*>(hudTarget);
        if (n)
            n->remove();
        }
      }

    //enable physics simulation
    if (key=='s')                               //pressed s
      renderer->bUpdatePhysics=!renderer->bUpdatePhysics;

    if (key==4 && selectedActors.size()>0){            //ctrl-d
        copySelected();
    }

    if (key=='P'){                              //shift-p
        staticButton=(Button*)renderer->actorInfo["18CreatePrefabButton"].actorReference;
        staticButton->location=Vector3f(screenX/2-200,screenY/2-50,0);
        staticButton->color=Vector4f(0.0,0.0,1.0,1.0);
        staticButton->name="name your prefab";
        staticButton->clickedLeft();
        renderer->buttonList.push_back(staticButton);
        }

    if (key=='G' && selectedActors.size()>1){            //shift-g
       makeGroup();
    }

   cout << (int)key << endl;
  }
}


void Input::specialKeyUp (int key,int x, int y){

if (key==GLUT_KEY_LEFT && keyVector.x==-1)
       keyVector.x=0;
if (key==GLUT_KEY_RIGHT && keyVector.x==1)
       keyVector.x=0;

if (key==GLUT_KEY_PAGE_UP)
       keyVector.y=0;
if (key==GLUT_KEY_PAGE_DOWN)
       keyVector.y=0;


if (key==GLUT_KEY_UP)
       Input::keyVector.z=0;
if (key==GLUT_KEY_DOWN)
       keyVector.z=0;

if (key==GLUT_KEY_F1)
        renderer->bCollisionOnly=!renderer->bCollisionOnly;

//TODO: this actually has to be implemented :-)
if (key==GLUT_KEY_F2)
        renderer->bDrawHelpers=!renderer->bDrawHelpers;

if (key==GLUT_KEY_F3);



if (key==GLUT_KEY_F4)
        renderer->bShowMenu=!renderer->bShowMenu;
}

void Input::selectActor(int button){


    if (bShiftDown){                                                                //adding to selection
        bool foundInSelection=false;
        for (int i=0;i<(int)selectedActors.size();i++){
            if (worldTarget==selectedActors[i])
                foundInSelection=true;                                              //only add if we're not already in selection
            }
        if (!foundInSelection){
            if (worldTarget->groupID!="NULL" && !bCtrlDown){                        //if we're part of a group, add the whole group
                for (int i=0;i<(int)renderer->actorList.size();i++){                //unless we hold down ctrl, then only add this one!
                    if (renderer->actorList[i]->groupID==worldTarget->groupID){
                        renderer->actorList[i]->bSelected=true;
                        selectedActors.push_back(renderer->actorList[i]);
                        createNewSelectionMarker(renderer->actorList[i]);
                        }
                    }
                }
            else{
                worldTarget->bSelected=true;
                selectedActors.push_back(worldTarget);                              //no CTRL or no group, but SHIFT down, so should add
                createNewSelectionMarker(worldTarget);
                }
            }
        }
    else{
        bool foundInSelection=false;
        for (int i=0;i<(int)selectedActors.size();i++){
            if (worldTarget==selectedActors[i])
                foundInSelection=true;                                              //check if we're not already in selection
            }
        if (!foundInSelection && button==MOUSEBTNLEFT){                                                     //if we're clicking on a actor not already in selection, you can go ahead
            deselectActors();
            if (worldTarget->groupID!="NULL" && !bCtrlDown){                            //if we're part of a group, select the whole group
                for (int i=0;i<(int)renderer->actorList.size();i++){                    //unless we hold down CTRL, then only select me
                    if (renderer->actorList[i]->groupID==worldTarget->groupID){
                        renderer->actorList[i]->bSelected=true;
                        selectedActors.push_back(renderer->actorList[i]);
                        createNewSelectionMarker(renderer->actorList[i]);
                        }
                    }
                }
            else{
                worldTarget->bSelected=true;
                selectedActors.push_back(worldTarget);                                  //no CTRL or no Group
                createNewSelectionMarker(worldTarget);
                }
            }
        else if (!foundInSelection && button==MOUSEBTNRIGHT){                           //not in selection and clicked right
                worldTarget->bSelected=true;
                selectedActors.push_back(worldTarget);
                createNewSelectionMarker(worldTarget);
                }
        }

}

void Input::deselectButtons(int depth){

cout << "deselecting!" << endl;

if (actorMenu)
  actorMenu->deselect(depth);


vector<Button*>::iterator it;
//make sure all Buttons are cleaned up!

    for (it=renderer->buttonList.end()-1;it>=renderer->buttonList.begin();it--){
        (*it)->deselect(depth);
        }
}

void Input::deselectActors(){

    selectedActors.clear();
    for (int i=0;i<(int)selectionMarkers.size();i++){
        selectionMarkers[i]->base->bSelected=false;
        delete(selectionMarkers[i]);
        }
    selectionMarkers.clear();
    cout << "clearing selection stack..." << endl;
}

void Input::copySelected(){

    cout << "copying..." << endl;
    for (int i=0;i<(int)selectedActors.size();i++){
        const std::type_info* myType=&(typeid(*selectedActors[i]));
        Actor * A=renderer->actorInfo[myType->name()].actorReference;
        A->create();

        TiXmlElement * root = new TiXmlElement( "Moviesandbox" );
        A=renderer->actorList[renderer->actorList.size()-1];
        A->load(selectedActors[i]->save(root));
        delete root;
        A->bSelected=false;                                             //flip selection when copying!
        A->setup();
        }
    //renderer->actorList.push_back(A);

}

void Input::makePrefab(std::string prefabName){

        //assemble TiXmlElement of all selected Actors
        TiXmlElement* myPrefab = new TiXmlElement("MovieSandbox");
        //save in order of actorList for later referencing!
        for (int i=0;i<(int)renderer->actorList.size();i++){
            for (int j=0;j<(int)selectedActors.size();j++)
                if (renderer->actorList[i]==selectedActors[j]){
                    renderer->actorList[i]->bSelected=false;                            //don't pre-select when making a prefab!
                    myPrefab->LinkEndChild(renderer->actorList[i]->save(myPrefab));
                    renderer->actorList[i]->bSelected=true;
                    }
        }
        //save to disk
        TiXmlDocument doc;
        TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
        doc.LinkEndChild( decl );
        doc.LinkEndChild(myPrefab);
        string stringName="resources/prefabs/"+prefabName+".prefab";
        doc.SaveFile(stringName);
        prefabs.push_back(prefabName+".prefab");
}

void Input::makeGroup(){
        TextInputButton* messageWindow=new TextInputButton;
        messageWindow->name="GroupName:";
        messageWindow->bMessageWindow=true;
        messageWindow->parent=selectedActors[0];
        messageWindow->buttonProperty="GROUPID";
        messageWindow->location=Vector3f(screenX/2-200,screenY/2-50,0);
        messageWindow->scale=Vector3f(100,50,1);
        messageWindow->sceneShaderID="color";
        focusButton=messageWindow;
        messageWindow->level=100;
        messageWindow->setup();
        messageWindow->bDrawName=true;
        messageWindow->color=Vector4f(1.0,0.2,0.2,1.0);
        renderer->buttonList.push_back(messageWindow);
        messageWindow->clickedLeft();
}

void Input::createNewSelectionMarker(Actor* selectedActor){

    Actor* marker=new Actor;
    marker->drawType=DRAW_SPRITE;
    marker->scale=Vector3f(1,1,1);
    marker->color=Vector4f(1.0,0.0,0.0,1.0);
    marker->sceneShaderID="color";
    marker->base=selectedActor;
    selectionMarkers.push_back(marker);
}


//Display and Textdrawing
void Input::displayDebug(){

double deltaTime=0;

//shift buffer
for (int i=FPSBUFFERSIZE-1;i>0;i--)
  Input::fpsBuffer[i]=Input::fpsBuffer[i-1];

//update buffer
Input::fpsBuffer[0]=renderer->deltaTime;

//calculate buffer
for (int i=0;i<FPSBUFFERSIZE;i++)
  deltaTime+=Input::fpsBuffer[i];

deltaTime=deltaTime/FPSBUFFERSIZE;

char string[30];
sprintf(string,"FPS: %4.2f",1000/deltaTime);
drawText(string,screenX-screenX*0.75,20 );
char particleNumber[30];
sprintf(particleNumber,"Number of Particles: %i", numParticles);
drawText(particleNumber,screenX-screenX*0.75,50 );
}

void Input::drawText(string str, float x, float y){

 glColor4f(1.0,1.0,1.0,1.0);
 verdana.drawString(str, x, y);
}

void Input::drawText(string str, float x, float y, Vector4f col, float fontSize){

}

//TODO: load textures/meshes/stuff seperately or save it always too!
void Input::saveAll(std::string filename){

    TiXmlDocument doc;
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild( decl );
    TiXmlElement * root = new TiXmlElement( "Moviesandbox" );
    doc.LinkEndChild( root );

    //save controller location and rotation
    TiXmlElement * controlElement=new TiXmlElement("Controller");
    controlElement->SetAttribute("Location",controller->memberToString(&controller->property["LOCATION"]));
    controlElement->SetAttribute("Rotation",controller->memberToString(&controller->property["ROTATION"]));
    root->LinkEndChild(controlElement);

    //first Actors
    for (unsigned int i=0;i<renderer->actorList.size();i++)
      {
      TiXmlElement * actorElement=renderer->actorList[i]->save(root);
      root->LinkEndChild(actorElement);
      }

    //then saveable Buttons
    for (unsigned int i=0;i<renderer->saveableButtonList.size();i++)
      {
      TiXmlElement * buttonElement=renderer->saveableButtonList[i]->save(root);
      root->LinkEndChild(buttonElement);
      }
    //then nodes
    for (unsigned int i=0;i<renderer->nodeList.size();i++)
      {
      TiXmlElement * nodeElement=renderer->nodeList[i]->save(root);
      root->LinkEndChild(nodeElement);
      }

    string saveString=savedSceneDirName;
    saveString.append(filename);

    cout << "saving filename: " << saveString << endl;

    doc.SaveFile( saveString );
}

void Input::loadAll(std::string fileName){


    //load prefabs
    getAllPrefabs();

    //clean Up
    if (renderer->actorList.size()>0){
        for (int i=(int)renderer->actorList.size()-1;i>=0;i--)
            renderer->actorList[i]->remove();
    }

    if (renderer->helperList.size()>0){
        for (int i=(int)renderer->helperList.size()-1;i>=0;i--)
            renderer->helperList[i]->remove();
    }

    if (renderer->nodeList.size()>0){
        for (int i=(int)renderer->nodeList.size()-1;i>=0;i--)
            renderer->nodeList[i]->remove();
    }

    if (renderer->buttonList.size()>0){
        for (int i=(int)renderer->buttonList.size()-1;i>=0;i--)
            if (renderer->buttonList[i]->level>0)
                renderer->buttonList[i]->remove();
    }



    string stringName=savedSceneDirName;
    stringName.append(fileName);

    cout << "Loading file..." << stringName <<endl;


    TiXmlDocument doc( stringName );
    if (!doc.LoadFile()) return;


    loadMeshes(renderer->library);
    loadTextures(renderer->library);
    loadShaders(renderer->library);
    loadActionList(renderer->library);


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);

    //***********************************************************************
    //Make sure this is a Moviesandbox file!
    //***********************************************************************

    element=hDoc.FirstChildElement().Element();
    if (!element) return;

    hRoot=TiXmlHandle(element);

    //***********************************************************************
    //Load Actor List
    //***********************************************************************

    //loading is a two step process
    int listPos=0;

    //load controller locations
    cout << "loading camera Position..." << endl;
    element=hRoot.FirstChild( "Controller" ).Element();
    if (element){
        string cLoc=element->Attribute("Location");
        controller->memberFromString(&controller->property["LOCATION"], cLoc);
        string cRot=element->Attribute("Rotation");
        controller->memberFromString(&controller->property["ROTATION"], cRot);
        controller->processMove(0.0);
    }
    else cout << "no position info found... skipping..." << endl;

    cout << "loading actors..." << endl;

    //first create all Actors

      element=hRoot.FirstChild( "Actor" ).Element();
      string myType;
      for( ; element!=NULL; element=element->NextSiblingElement("Actor"))
        {
        cout << "next element: " << element->Value() << " " << element->GetText() <<endl;
        myType=element->GetText();
        Actor * A=renderer->actorInfo[myType].actorReference;
        A->create();
        }


    //then load all properties - for referencing reasons
      element=hRoot.FirstChild( "Actor" ).Element();
      for( ; element!=NULL; element=element->NextSiblingElement("Actor"))
        {
        Actor* A=renderer->actorList[listPos];
        myType=element->GetText();
        //***********************************************************************
        //Fill up Properties
        //***********************************************************************
        A->load(element);
        listPos++;
        }

    //then setup all actors, so properties are already present!
    for (int i=0;i<(int)renderer->
    actorList.size();i++){
            renderer->actorList[i]->setup();
    }

    //***********************************************************************
    //Load Button List
    //***********************************************************************
    listPos=0;

    cout << "loading buttons..." << endl;

      element=hRoot.FirstChild( "Button" ).Element();
      for( ; element!=NULL; element=element->NextSiblingElement("Button"))
        {
        cout << element->Value() << " " << element->GetText() <<endl;
        myType=element->GetText();
        Button* B=(Button*)renderer->actorInfo[myType].actorReference;
        B->create();
        }

      element=hRoot.FirstChild( "Button" ).Element();
      for( ; element!=NULL; element=element->NextSiblingElement("Button"))
        {
        Button* B=renderer->saveableButtonList[listPos];
        myType=element->GetText();
        //***********************************************************************
        //Fill up Properties
        //***********************************************************************
        B->load(element);
        B->setup();
        listPos++;
        }

    //***********************************************************************
    //Load Node List
    //***********************************************************************
    listPos=0;

    cout << "loading nodes..." << endl;

      element=hRoot.FirstChild( "Node" ).Element();
      for( ; element!=NULL; element=element->NextSiblingElement("Node"))
        {
        cout << element->Value() << " " << element->GetText() <<endl;
        myType=element->GetText();
        Node* N=(Node*)renderer->actorInfo[myType].actorReference;
        N->create();
        }

      element=hRoot.FirstChild( "Node" ).Element();
      for( ; element!=NULL; element=element->NextSiblingElement("Node"))
        {
        Node* N=renderer->nodeList[listPos];
        myType=element->GetText();
        //***********************************************************************
        //Fill up Properties
        //***********************************************************************
        N->load(element);
        listPos++;
        }
      for (uint i=0; i< renderer->nodeList.size();i++){
        renderer->nodeList[i]->setup();
        }

}

void Input::loadMeshes(std::string fileName){

    TiXmlDocument doc(fileName);
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);
    element=hDoc.FirstChildElement().Element();
    // should always have a valid root but handle gracefully if it doesn't
    if (!element) return;

    // save this for later
    hRoot=TiXmlHandle(element);
    //***********************************************************************
    //Load OBJs
    //***********************************************************************
      element=hRoot.FirstChild( "Mesh" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("Mesh")){
        string meshID=element->Attribute("meshID");
        string meshFileName=element->Attribute("meshFilename");
        renderer->meshList[meshID]=LoadOBJ(meshFileName.c_str());
        cout << "loading mesh " << meshID << endl;
      }

    //***********************************************************************
    //Load complex Meshes
    //***********************************************************************
      element=hRoot.FirstChild( "ColladaMesh" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("ColladaMesh")){
        string meshID=element->Attribute("meshID");
        string meshFileName=element->Attribute("meshFilename");
        renderer->colladaLoader->loadColladaMesh(meshFileName, meshID);
        cout << "loading mesh " << meshID << endl;
      }

    //***********************************************************************
    //Load sprite Meshes
    //***********************************************************************
      element=hRoot.FirstChild( "SpriteMesh" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("SpriteMesh")){
        string meshID=element->Attribute("meshID");
        string meshFileName=element->Attribute("meshFilename");
        renderer->spriteMeshLoader->loadSpriteMesh(meshFileName, meshID);
        cout << "loading sprite mesh " << meshID << endl;
      }


}

void Input::loadPrefab(std::string fileName){

    //loading is a two step process
    int listPos=renderer->actorList.size();


    cout << "loading Prefab from... "<< fileName << endl;
    //first create all Actors
    TiXmlDocument doc(fileName);
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);

    element=hDoc.FirstChildElement().Element();
    element= element->FirstChildElement("Actor");

      string myType;
      for( ; element!=NULL; element=element->NextSiblingElement("Actor"))
        {
        cout << "next element: " << element->Value() << " " << element->GetText() <<endl;
        myType=element->GetText();
        Actor * A=renderer->actorInfo[myType].actorReference;
        A->create();
        }


    //then load all properties - for referencing reasons
    element=hDoc.FirstChildElement().Element();
    element= element->FirstChildElement("Actor");

    //for relative loading
    int loadPos=listPos-1;

      for( ; element!=NULL; element=element->NextSiblingElement("Actor"))
        {
        Actor* A=renderer->actorList[listPos];

        //***********************************************************************
        //Fill up Properties
        //***********************************************************************
        A->actorOffset=loadPos;         //for relative actor references

        A->load(element);

//        if (A->base)
//            A->baseMatrix=A->baseMatrix;
            //cout << A->base->name << endl;


        A->actorOffset=0;               //set back to zero
        A->setup();
        selectedActors.push_back(A);                                         //push newly created buttons in selection stack
        createNewSelectionMarker(A);
        listPos++;
        }

 //   makeGroup();
}

void Input::loadAction(std::string fileName){


    TiXmlDocument doc(fileName);
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);

    //***********************************************************************
    //Load Action
    //***********************************************************************
    cout << "loading actions..." << endl;

    element=hDoc.FirstChildElement().Element();
    element= element->FirstChildElement("Action");
    std::string myType=element->GetText();
    Action* AC=(Action*)renderer->actorInfo[myType].actorReference;
    AC->create();

    AC=(Action*)renderer->buttonList.back();
    AC->load(element);
    renderer->actionList[AC->name]=AC;
    AC->setup();
}

void Input::loadTextures(string fileName){

    TiXmlDocument doc( fileName );
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);


    element=hDoc.FirstChildElement().Element();
    // should always have a valid root but handle gracefully if it doesn't
    if (!element) return;

    // save this for later
    hRoot=TiXmlHandle(element);

    //***********************************************************************
    //Load textures
    //***********************************************************************
      element=hRoot.FirstChild( "Texture" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("Texture")){
        int val=0;

        string texID=element->Attribute("textureID");
        string texFileName=element->Attribute("filename");
        string nextFrame="NULL";
        if (element->Attribute("nextFrame"))
            nextFrame=element->Attribute("nextFrame");

        float frameRate = 0.0f;
        if (element->Attribute("frameRate"))
        {
            element->Attribute("frameRate",&val);
            frameRate=float(val);
        }

        element->Attribute("bAlpha", &val);
        bool bAlpha=bool(val);

        element->Attribute("bWrap", &val);
        bool bWrap=bool(val);

        renderer->LoadTextureTGA(texFileName,bWrap,bAlpha, texID);
        renderer->textureList[texID]->nextTexture=nextFrame;
        renderer->textureList[texID]->frameRate=frameRate;
        cout << "loading texture " << texID << endl;
      }
}

void Input::loadShaders(string fileName){

    TiXmlDocument doc( fileName );
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);


    element=hDoc.FirstChildElement().Element();
    // should always have a valid root but handle gracefully if it doesn't
    if (!element) return;

    // save this for later
    hRoot=TiXmlHandle(element);

    //***********************************************************************
    //Load shaders
    //***********************************************************************
      element=hRoot.FirstChild( "Shader" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("Shader")){
        string shaderID=element->Attribute("shaderID");
        string vertexFileName=element->Attribute("vertexShaderFilename");
        string fragmentFileName=element->Attribute("fragmentShaderFilename");
        renderer->loadShader(vertexFileName,fragmentFileName, shaderID);
        cout << "loading shader " << shaderID << endl;
      }
}

void Input::loadActionList(string fileName){

    TiXmlDocument doc( fileName );
    if (!doc.LoadFile()) return;


    TiXmlHandle hDoc(&doc);
    TiXmlElement * element;
    TiXmlHandle hRoot(0);


    element=hDoc.FirstChildElement().Element();
    // should always have a valid root but handle gracefully if it doesn't
    if (!element) return;

    // save this for later
    hRoot=TiXmlHandle(element);

    //***********************************************************************
    //Load shaders
    //***********************************************************************
      element=hRoot.FirstChild( "Action" ).Element();
      for ( ; element!=NULL ;element=element->NextSiblingElement("Action")){
        string actionFileName=element->Attribute("actionFilename");
        loadAction("resources/actions/"+actionFileName);
        cout << "loading action " << actionFileName << endl;
      }

}

//TODO: this is windows territory!
void Input::getAllDrawings(){

    cout << "getting drawings..." << endl;

    savedDrawings.clear();

    //not used?
    //char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\drawings\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
          {
		  cout << fd.cFileName << endl;
		  savedDrawings.push_back(fd.cFileName);
          }
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllScenes(){

    cout << "getting scenes..." << endl;

    savedScenes.clear();

    //never used?
    //char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\scenes\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  savedScenes.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllImages(){

    cout << "getting Images..." << endl;

    userImages.clear();

    //char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\images\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  userImages.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllBrushes(){


    cout << "getting Brushes..." << endl;

    userBrushes.clear();

    //char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\brushes\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  userBrushes.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}

void Input::getAllPrefabs(){

    //char path[MAX_PATH];
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	HANDLE hFind = FindFirstFile( "resources\\prefabs\\*", &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
	    do{
		if( !(fd.dwFileAttributes & dwAttr))
		  prefabs.push_back(fd.cFileName);
        }while (FindNextFile( hFind, &fd));

		FindClose( hFind);
	}
}


//************************************************************
//
//       3D and general Helper functions
//
//
//************************************************************

float Input::convertToGrid(float nonGrid){

return (gridSize*(int)(nonGrid/gridSize));// - nonGridRounded%gridSizeRounded)*0.001);
//return 0.0f;
}

float Input::setToRange(float min, float max, float value){
    //multiply by difference of max and min     //and add minimum
    return( value   *   (max-min)     +   min);
}


/* FONT OPTIONS

The font options available are:

# GLUT_BITMAP_8_BY_13
# GLUT_BITMAP_9_BY_15
# GLUT_BITMAP_TIMES_ROMAN_10
# GLUT_BITMAP_TIMES_ROMAN_24
# GLUT_BITMAP_HELVETICA_10
# GLUT_BITMAP_HELVETICA_12
# GLUT_BITMAP_HELVETICA_18

*/

/* SPECIAL GLUT KEY NUMBERS

Special Keys:

GLUT_KEY_F1		F1 function key
GLUT_KEY_F2		F2 function key
GLUT_KEY_F3		F3 function key
GLUT_KEY_F4		F4 function key
GLUT_KEY_F5		F5 function key
GLUT_KEY_F6		F6 function key
GLUT_KEY_F7		F7 function key
GLUT_KEY_F8		F8 function key
GLUT_KEY_F9		F9 function key
GLUT_KEY_F10		F10 function key
GLUT_KEY_F11		F11 function key
GLUT_KEY_F12		F12 function key
GLUT_KEY_LEFT		Left function key
GLUT_KEY_RIGHT		Up function key
GLUT_KEY_UP		Right function key
GLUT_KEY_DOWN		Down function key
GLUT_KEY_PAGE_UP	Page Up function key
GLUT_KEY_PAGE_DOWN	Page Down function key
GLUT_KEY_HOME		Home function key
GLUT_KEY_END		End function key
GLUT_KEY_INSERT		Insert function key


*/
